package com.example.lock;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.FloatMath;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.LinearInterpolator;

import androidx.annotation.Nullable;

/**
 * @ClassName: LockView
 * @Description: 解锁view
 * @Author: Shangqs
 * @E-mail:1037105071@qq.com
 * @CreateDate: 2021/5/19 13:40
 */
public class LockView extends View {
    private int viewHeight, viewWidth;
    private Paint paint;
    private int r;
    private int centerX, centerY;
    //中心时左上角坐标
    private int centerbp_lt_x, centerbp_lt_y;
    //触摸坐标
    private int x, y;
    private int upX, upY;
    //原图宽高
    private int initBtwidth, initBtheight;
    //缩放后宽高
    private int realBtwidth, realBtHeight;
    private Bitmap bitmap;
    private Bitmap scalBitmap;


    /**
     * 滑块当前的状态
     */
    public int currentState = 1;

    /**
     * 默认位置
     */
    public static final int STATE_DEFAULT = 1;

    /**
     * 解锁位置
     */
    public static final int STATE_UNLOCK = 2;
    /**
     * 正在拖拽
     */
    public static final int STATE_MOVING = 3;
    private OnLockSuccessListener lockListener;

    private boolean isDownLock;

    private float ovelTop;
   // private int txtSize = 56;
    private float canvasOffsetX,canvasOffsetY;
    //位置是否居中 0-居中 1-左
    private int viewpos;

    public LockView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.lockView);
         viewpos = typedArray.getInteger(R.styleable.lockView_gravity, 0);

        typedArray.recycle();

        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.parseColor("#a0000000"));
        bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.locks);
        initBtwidth = bitmap.getWidth();
        initBtheight = bitmap.getHeight();
    }

    private void resetPain() {
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.parseColor("#a0000000"));
    }

    private void animtorStart() {
        ValueAnimator animatorW = ValueAnimator.ofInt(upX, centerX);
        ValueAnimator animatorH = ValueAnimator.ofInt(upY, centerY);
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.setDuration(400);
        animatorSet.setInterpolator(new LinearInterpolator());
        animatorSet.play(animatorW).with(animatorH);
        animatorW.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int value = (int) animation.getAnimatedValue();
                x = value;
                if (x == centerX) {
                    currentState = STATE_DEFAULT;
                }
                postInvalidate();
            }
        });
        animatorH.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int value = (int) animation.getAnimatedValue();
                y = value;
                if (y == centerY) {
                    currentState = STATE_DEFAULT;
                    lockListener.fail();
                }
                postInvalidate();

            }
        });
        animatorSet.start();
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        if (widthMode == MeasureSpec.AT_MOST && heightMode == MeasureSpec.AT_MOST) {
            widthSize = 400;
            heightSize = 400;
            setMeasuredDimension(widthSize, heightSize);
        } else if (widthMode == MeasureSpec.AT_MOST) {
            widthSize = 400;
            setMeasuredDimension(widthSize, heightSize);
        } else if (heightMode == MeasureSpec.AT_MOST) {
            heightSize = 400;
            setMeasuredDimension(widthSize, heightSize);
        }else{
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        resetPain();
        //处理padding值，以后处理吧
        int paddingLeft = getPaddingLeft();
        int paddingTop = getPaddingTop();
        int paddingRight = getPaddingRight();
        int paddingBottom = getPaddingBottom();

        viewHeight = getMeasuredHeight();
        viewWidth = getMeasuredWidth();
        r = (int) (Math.min(viewHeight, viewWidth) / 2 * 0.75);
        canvasOffsetX=canvasOffsetY = r * 0.25f;
        if (viewpos ==2) {
            canvasOffsetX=viewWidth / 2 - r;
            canvasOffsetY=viewHeight / 2 - r;
        }
        canvas.translate(canvasOffsetX, canvasOffsetY);


        centerX = centerY = r;

        if (currentState == STATE_UNLOCK) {
            paint.setColor(Color.parseColor("#929292"));
        }
        canvas.drawCircle(r, r, r, paint);
        float rectFwidth = r * 2;
        float rectFheight = r;
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        ovelTop = r + r - rectFheight / 2;
        RectF rectF = new RectF(r - rectFwidth / 2, r + r - rectFheight / 2, r + rectFwidth / 2, r + r + rectFheight / 2);
        paint.setColor(Color.parseColor("#929292"));
        canvas.drawOval(rectF, paint);
        paint.setXfermode(null);

        float scale = r / (Math.max(initBtwidth, initBtheight) * 2f);
      //  txtSize = (int) (scale * txtSize);
        //settextsize属性一定要放在getFontMetricsInt()之前，否则测量有误差
        paint.setTextSize(getResources().getDimension(R.dimen.paintsize));
        Paint.FontMetricsInt fmi = paint.getFontMetricsInt();
        float baseline = (float) (r + r - rectFheight / 4 - (fmi.bottom / 2.0 + fmi.top / 2.0));
        paint.setColor(Color.WHITE);
        String text = "拖 拽 解 锁";
        float width = paint.measureText(text);
        switch (currentState) {
            case 1:
                if (scalBitmap == null) {
                    Matrix matrix = new Matrix();
                    matrix.setScale(scale, scale);
                    scalBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
                    bitmap.recycle();
                    realBtwidth = scalBitmap.getWidth();
                    realBtHeight = scalBitmap.getHeight();
                    centerbp_lt_x = centerX - scalBitmap.getWidth() / 2;
                    centerbp_lt_y = centerY - scalBitmap.getHeight() / 2;

                }
                canvas.drawText(text, r - width / 2, baseline, paint);
                canvas.drawBitmap(scalBitmap, centerbp_lt_x, centerbp_lt_y, paint);


                break;
            case 2:
                canvas.drawBitmap(scalBitmap, x - realBtwidth / 2, y - realBtHeight / 2, paint);
                break;
            case 3:
                canvas.drawText(text, r - width / 2, baseline, paint);
                canvas.drawBitmap(scalBitmap, x - realBtwidth / 2, y - realBtHeight / 2, paint);
                break;
        }




    }





    @Override
    public boolean onTouchEvent(MotionEvent event) {

        x = (int) (event.getX() - canvasOffsetX);
        y = (int) (event.getY() - canvasOffsetY);

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                isDownLock = isDownOnLock(x, y);
                lockListener.draging();
                break;
            case MotionEvent.ACTION_MOVE:
//                int dx =
//                Math.hypot()
                Log.e("SQS","LockView--onmove");
                if (isDownLock && isDownOnCircle(x, y)) {
                    currentState = STATE_MOVING;
                    if (isCanUnLock(y)) {
                        currentState = STATE_UNLOCK;
                    }
                   postInvalidate();

                }
                break;
            case MotionEvent.ACTION_UP:
                if (isDownLock) {
                    if (isCanUnLock(y)) {
                        currentState = STATE_UNLOCK;
                        if (lockListener != null) {
                            lockListener.success();
                        }
                        resetLockView();
                        return true;
                    }

                    upX = x;
                    upY = y;
                    animtorStart();

                }
                break;
        }

        return true;
    }

    private void resetLockView(){
        currentState=1;
        postInvalidate();
    }

    /**
     * 设置解锁成功监听
     *
     * @param lockListener
     */
    public void setOnLockListener(OnLockSuccessListener lockListener) {
        this.lockListener = lockListener;
    }

    public interface OnLockSuccessListener {
        void success();
        void fail();
        void draging();
    }

    /**
     * 判断是否在圆内
     *
     * @param x
     * @param y
     * @return
     */
    public boolean isDownOnCircle(float x, float y) {
        double sqrt = Math.sqrt(Math.pow(Math.abs(centerX - x), 2) + Math.pow(Math.abs(centerY - y), 2));
        if (sqrt <= r) {
            return true;
        }
        return false;
    }

    /**
     * 是否点锁
     *
     * @param x
     * @param y
     * @return
     */
    public boolean isDownOnLock(float x, float y) {
        if (x > centerbp_lt_x && x < centerbp_lt_x + realBtHeight && y > centerbp_lt_y && y < centerbp_lt_y + realBtHeight) {
            return true;
        }
        return false;
    }

    /**
     * 判断是否拖动到了解锁处
     */
    public boolean isCanUnLock(int y) {
        if (y + realBtHeight / 2 > ovelTop) return true;
        return false;
    }


}